package cn.yujiago.miaosha.interceptor;

import java.io.OutputStream;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.yujiago.miaosha.access.AccessLimit;
import cn.yujiago.miaosha.component.UserContext;
import cn.yujiago.miaosha.dto.CodeMsg;
import cn.yujiago.miaosha.dto.Result;
import cn.yujiago.miaosha.redis.AccessKey;
import cn.yujiago.miaosha.redis.RedisService;
import cn.yujiago.miaosha.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSON;

// 拦截标注@AccessLimit注解的方法
@Component
public class AccessInterceptor extends HandlerInterceptorAdapter {
	
	@Autowired
	private RedisService redisService;
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

		if(handler instanceof HandlerMethod) {
			HandlerMethod handlerMethod = (HandlerMethod)handler;
			AccessLimit accessLimit = handlerMethod.getMethodAnnotation(AccessLimit.class);
			if(accessLimit == null) {
				return true;
			}
			// 指定时间段
			int seconds = accessLimit.seconds();
			// 访问次数
			int maxCount = accessLimit.maxCount();
			// 是否需要登录
			boolean needLogin = accessLimit.needLogin();

			if(needLogin) {
				if(UserContext.getUser() == null) {
					render(response, CodeMsg.SESSION_ERROR);
					return false;
				}
			}

			AccessKey accessKey = AccessKey.withExpire(seconds);
			// key : URI_userId
			String key = request.getRequestURI();
			key += "_" + UserContext.getUser().getId();
			Integer count = redisService.get(accessKey, key, Integer.class);
			// 检查访问次数
	    	if(count == null) {
	    		 redisService.set(accessKey, key, 1);
	    	}else if(count < maxCount) {
	    		 redisService.incr(accessKey, key);
	    	}else {
	    		render(response, CodeMsg.ACCESS_LIMIT_REACHED);
	    		return false;
	    	}
		}
		return true;
	}
	
	private void render(HttpServletResponse response, CodeMsg cm)throws Exception {
		response.setContentType("application/json;charset=UTF-8");
		OutputStream out = response.getOutputStream();
		String str  = JSON.toJSONString(Result.error(cm));
		out.write(str.getBytes("UTF-8"));
		out.flush();
		out.close();
	}

}
